#include <boost/asio.hpp>

#include <iostream>

using std::cout , std::cin, std::cerr, std::endl;
using std::string;

namespace asio = boost::asio;
namespace ip = boost::asio::ip;

const size_t MESSAGE_SIZE = 1024;

int main(int argc, char* argv[])
{
    try
    {
        // io_context
        auto io_context { asio::io_context() };
        // create endpoint
        auto remote_endpoint = ip::tcp::endpoint(ip::address::from_string("127.0.0.1"), 10120);
        auto socket = ip::tcp::socket(io_context, ip::tcp::v4());
        auto error_code = boost::system::error_code(boost::asio::error::host_not_found);
        socket.connect(remote_endpoint, error_code);

        if (error_code)
        {
            std::cout << error_code.message() << std::endl;
            return 0;
        }

        auto send_buffer_p { std::make_unique<char[]>(MESSAGE_SIZE) };
        std::cout << "Enter message: " << std::endl;
        std::cin.getline(send_buffer_p.get(), MESSAGE_SIZE);
        size_t len = std::strlen(send_buffer_p.get());

        std::cout << "Sending message: " << send_buffer_p.get() << std::endl;
        asio::write(socket, asio::buffer(send_buffer_p.get(), len));
        std::cout << "Sending message complete." << std::endl;

        auto receive_buffer_p = std::make_unique<char[]>(MESSAGE_SIZE);
        std::size_t received_size = asio::read(socket, asio::buffer(receive_buffer_p.get(), len));
        std::cout << "Received size: " << received_size << std::endl;
        std::cout << "Received data: " << std::endl;
        std::cout.write(receive_buffer_p.get(), received_size);
        std::cout << std::endl;
    }
    catch (const boost::system::system_error& e)
    {
        std::cerr << e.code() << ": " << e.what() << std::endl;
    }
    return 0;
}
